package com.halachawiki.client.login;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.halachawiki.client.login.LoginService.Status;
import com.halachawiki.shared.FieldVerifier;

public class ChangePasswordControl {
	private LoginServiceAsync loginService = GWT.create(LoginService.class);
	private LoginConstants Constants = GWT.create(LoginConstants.class);

	private VerticalPanel root = new VerticalPanel();
	
	public VerticalPanel getRoot() { return root; }
	
	public void draw() {
		
		root.clear();
		
		// Build UI elements
		Label header = new Label(Constants.changePasswordHeader()); 
		header.setStyleName("gwt-label-login");
		root.add(header);
		
		FlexTable flexTable = new FlexTable();
		root.add(flexTable);
	
		Label oldPasswordLabel = new Label(Constants.oldPasswordField());
		flexTable.setWidget(1, 0, oldPasswordLabel);
		final TextBox oldPassword = new PasswordTextBox();
		flexTable.setWidget(1, 1, oldPassword);
		
		Label newPasswordLabel = new Label(Constants.newPasswordField());
		flexTable.setWidget(2, 0, newPasswordLabel);
		final PasswordTextBox newPassword = new PasswordTextBox();
		flexTable.setWidget(2, 1, newPassword);

		Label confirmPasswordLabel = new Label(Constants.confirmPasswordField());
		final PasswordTextBox confirmPassword = new PasswordTextBox();
		flexTable.setWidget(3, 0, confirmPasswordLabel);
		flexTable.setWidget(3, 1, confirmPassword);
		
		final Button nextButton = new Button(Constants.nextButton());
		flexTable.setWidget(4, 1, nextButton);
		
		final Label errorLabel = new Label();
		root.add(errorLabel);

		// build behavior
		oldPassword.addKeyPressHandler(new KeyPressHandler() {
			@Override
			public void onKeyPress(KeyPressEvent event) {
				if (event.getCharCode()==KeyCodes.KEY_ENTER) {
					newPassword.setFocus(true);
				}
			} });
		newPassword.addKeyPressHandler(new KeyPressHandler() {
			@Override
			public void onKeyPress(KeyPressEvent event) {
				if (event.getCharCode()==KeyCodes.KEY_ENTER) {
					confirmPassword.setFocus(true);
				}
			} });
		confirmPassword.addKeyPressHandler(new KeyPressHandler() {
			@Override
			public void onKeyPress(KeyPressEvent event) {
				if (event.getCharCode()==KeyCodes.KEY_ENTER) {
					nextButton.setFocus(true);
				}
			} });
		nextButton.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				if (!validatePassword(newPassword, errorLabel)) {
					newPassword.setFocus(true);
					return;
				}
				if (!newPassword.getText().equals(confirmPassword.getText())) {
					errorLabel.setText(Constants.passwordsDontMatch());
					newPassword.setFocus(true);
					return;
				}
				loginService.changePassword(oldPassword.getText(), newPassword.getText(), new AsyncCallback<Status>() {

					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub
						
					}

					@Override
					public void onSuccess(Status result) {
						if (result == Status.OK)
							success();
						if (result == Status.WRONG_PASSWORD)
							errorLabel.setText(Constants.wrongPassword());
						if (result == Status.GENERIC_ERROR)
							errorLabel.setText("An error has occurred");
					} });
			} } );

		oldPassword.setFocus(true);		
	}
	
	private void success() {
		root.clear();
		root.add(new Label(Constants.passwordChangedSuccessfully()));
	}
	
	boolean validatePassword(PasswordTextBox password, Label errorLabel) {
		if (!FieldVerifier.isValidPassword(password.getText())) {
			errorLabel.setText(Constants.invalidPassword());
			return false;
		}
		return true;
	}

}
